﻿module SVMBinaryLib

open SVMTypes

let char_digit_to_int (d : char) : int =
  //char conversion of a digit to an integer starts from 48 and ends to 57
  let d_encode = int d
  d_encode - 48

let char_digit_to_int64 (d : char) : int64 =
  //char conversion of a digit to an integer starts from 48 and ends to 57
  let d_encode = int64 d
  d_encode - 48L

//fill a list of integers with 0 up to the 8th element
let fill_digits (l : int list) : int list =
  let rec fill (l : int list) (step : int) (res : int list) : int list =
    match l with
    | [] when step < 8 -> fill l (step + 1) (res @ [0])
    | x :: xs -> fill xs (step + 1) (res @ [x])
    | _ -> res
  (fill (l |> List.rev) 0 []) |> List.rev

//convert a int64 number to a list of int containing its digits
let int_to_list (n : int64) : int list =
  let n_str = string n
  let rec tail_rec (n_chr : char list) (acc : int list) : int list =
    match n_chr with
    | [] -> acc
    | c :: cs -> tail_rec cs (acc @ [char_digit_to_int c])
  tail_rec (n_str |> list_of_string) []

//convert a list of int digits in the corresponding int64 number given a representation in base b of l
let list_to_int (l : int list) (b : int) : int64 =
  let rec tail_rec (l : int list) (n_digit : int) (acc : int) =
    match l with
    | [] -> acc
    | x :: xs ->
        let p = (float b) ** (float n_digit) |> int
        tail_rec xs (n_digit + 1) (acc + x * p)
  (tail_rec (l |> List.rev) 0 0) |> int64

//convert a decimal number into its binary representation
let decimal_to_binary (n : int) : int64 =
  let rec tail_rec (n : int) (acc : int list) =
    match n with
    | 0 -> acc |> List.rev
    | _ -> tail_rec (n / 2) (acc @ [n % 2])
  list_to_int (tail_rec n []) 10

//convert a binary number into its decimal representation
let binary_to_decimal (n : int64) : int =
  let n_list = int_to_list n
  list_to_int n_list 2 |> int